/******************************************************************************
 * @File name   :      MemberPackageServiceImpl.java
 *
 * @Author      :      JIZHANGS
 *
 * @Date        :      Jul 28, 2015
 *
 * @Copyright Notice: 
 * Copyright (c) 2015 Capgemini, Inc. All  Rights Reserved.
 * This software is published under the terms of the Capgemini Software
 * License version 1.0, a copy of which has been included with this
 * distribution in the LICENSE.txt file.
 * 
 * 
 * ----------------------------------------------------------------------------
 * Date                   Who         Version        Comments
 * Jul 28, 2015 9:33:15 AM        JIZHANGS     1.0            Initial Version
 *****************************************************************************/
package com.cap.bts.crmdp.dealer.logistic.service.impl;

import java.io.InputStream;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cap.bts.commonfunc.common.service.IUniqueCodeGenerateService;
import com.cap.bts.crmdp.dealer.logistic.constants.LogisticConstants;
import com.cap.bts.crmdp.dealer.logistic.dao.IMaintainLogisticDao;
import com.cap.bts.crmdp.dealer.logistic.dto.LogisticImportResultDto;
import com.cap.bts.crmdp.dealer.logistic.dto.LogisticPrintDataDto;
import com.cap.bts.crmdp.dealer.logistic.dto.LogisticQueryDto;
import com.cap.bts.crmdp.dealer.logistic.dto.LogisticDataDto;
import com.cap.bts.crmdp.dealer.logistic.dto.LogisticResultsDto;
import com.cap.bts.crmdp.dealer.logistic.service.IMaintainLogisticService;
import com.cap.bts.framework.common.exception.AppException;
import com.cap.bts.framework.common.service.impl.BaseServiceImpl;
import com.cap.bts.framework.common.util.FileImportUtils;
import com.cap.bts.framework.common.util.Utils;

/**
 *
 */
@Transactional(rollbackFor = AppException.class)
@Service
public class MaintainLogisticServiceImpl extends BaseServiceImpl  implements IMaintainLogisticService {

    @Resource(name = "maintainLogisticDao")
    private IMaintainLogisticDao maintainLogisticDao;
    @Resource(name = "uniqueCodeGenerateqService")
    private IUniqueCodeGenerateService uniqueCodeGenerateService;
    private static final Logger LOGGER = Logger.getLogger(MaintainLogisticServiceImpl.class);
    @Autowired
    private MessageSource messageSource;
    /**
     * {@inheritDoc} 
     * overridden:
     * @Date        :      Jul 28, 2015
     * @see com.cap.bts.crmdp.dealer.purchase.service.IMemberPackageService#checkMemberPackageExsit(com.cap.bts.crmdp.dealer.purchase.dto.MemberPackageInfoSubmitDto)
    **/
    @Override
    public LogisticResultsDto queryLogisticData(LogisticQueryDto queryDto){
        LogisticResultsDto result = new LogisticResultsDto();
        if(queryDto != null) {
            List<LogisticDataDto> dataList = maintainLogisticDao.queryLogisticData(queryDto);
            result.setResultList(dataList);
            result.setSuccess(true);
        }
        return result;
    }

    /*
     * query records without paging
     * @see com.cap.bts.crmdp.dealer.logistic.service.IMaintainLogisticService#queryLogisticData(com.cap.bts.crmdp.dealer.logistic.dto.LogisticQueryDto)
     */
    @Override
    public LogisticResultsDto queryAllLogisticData(LogisticQueryDto queryDto){
        LogisticResultsDto result = new LogisticResultsDto();
        if(queryDto != null) {
            List<LogisticDataDto> dataList = maintainLogisticDao.queryAllLogisticData(queryDto);
            result.setResultList(dataList);
            result.setSuccess(true);
        }
        return result;
    }

    @Override
    public LogisticResultsDto queryLogisticDataForPrint(LogisticQueryDto queryDto){
        LogisticResultsDto result = new LogisticResultsDto();
        if(queryDto != null) {
            List<LogisticQueryDto> dto = maintainLogisticDao.logisticDataForPrintGroup(queryDto);
            List<LogisticPrintDataDto> dataList 
                    = maintainLogisticDao.queryLogisticDataForPrint(queryDto,dto);
            result.setResultForPrintList(dataList);
            result.setSuccess(true);
        }
        return result;
    }
    
    @Override
    public boolean insertLogisticInfo(LogisticDataDto dto){
        LogisticResultsDto result = new LogisticResultsDto();
        if(dto != null){
            String dealerId=maintainLogisticDao.getDealerId(dto.getDealerNo());
            if(Utils.isNullOrEmpty(dealerId)){
                return false;
            }
            String[] ary = dto.getCardName().split(";");
            for(String cardInfo: ary){
                String[] ar = cardInfo.split(",");
                dto.setType(ar[1]);
                dto.setShipAmount(ar[2]);
                Date shipDate=Date.valueOf(dto.getShipDate());
                dto.setShipDateVal(shipDate);
                if(!Utils.isNullOrEmpty(dto.getEstimatedArriveDate())){
                    Date estimatedArriveDate=Date.valueOf(dto.getEstimatedArriveDate());
                    dto.setEstimatedArriveDateVal(estimatedArriveDate);
                    }else{
                        dto.setEstimatedArriveDateVal(null);
                    }
                    maintainLogisticDao.insertLogisticInfo(dto,dealerId,ar[0]);
                }
            result.setSuccess(true);
        }
        return true;
    }
 
    
    @Override
    public LogisticDataDto queryLogisticDataById(String id){
        LogisticResultsDto results = new LogisticResultsDto();
        LogisticDataDto result = maintainLogisticDao.queryLogisticDataById(id);
        results.setSuccess(true);
        return result;
    }
    
    @Override
    public boolean editLogisticInfo(LogisticDataDto dto){
        LogisticResultsDto result = new LogisticResultsDto();
        if(Utils.isNullOrEmpty(dto.getEstimatedArriveDate())){
            maintainLogisticDao.updateLogisticInfo
            (dto.getId().toString(),Integer.parseInt(dto.getShipAmount()),Date.valueOf(dto.getShipDate()),
                null,dto.getExpressCom(),dto.getExpressNo(),dto.getUserId());
            }else{
                maintainLogisticDao.updateLogisticInfo
                (dto.getId().toString(),Integer.parseInt(dto.getShipAmount()),Date.valueOf(dto.getShipDate()),
                Date.valueOf(dto.getEstimatedArriveDate()),dto.getExpressCom(),dto.getExpressNo(),dto.getUserId());
                }
        result.setSuccess(true);
        return true;
    }

    @Override
    public boolean deleteLogisticInfo(String id){
        LogisticResultsDto result = new LogisticResultsDto();
        maintainLogisticDao.deleteLogisticInfo(id);
        result.setSuccess(true);
        return true;
    }

    @Override
    public LogisticResultsDto queryReceiveLogisticData(LogisticQueryDto queryDto){
        LogisticResultsDto result = new LogisticResultsDto();
        if(queryDto != null) {
            List<LogisticDataDto> dataList = maintainLogisticDao.queryReceiveLogisticData(queryDto);
            result.setResultList(dataList);
            result.setSuccess(true);
        }
        return result;
    }
    
    @Override
    public boolean receiveLogistic(String id,String cardDefId,int receiveAmount,String dealerId,String editor){
        LogisticResultsDto result = new LogisticResultsDto();
        maintainLogisticDao.receiveLogistic(id, receiveAmount, editor);
        String cardInfo = maintainLogisticDao.queryCardInventoryInfo(dealerId, cardDefId);
        if(!Utils.isNullOrEmpty(cardInfo)){
            String[] ar = cardInfo.split(",");
            maintainLogisticDao.updateCardInventory(ar[0], Integer.parseInt(ar[1])+receiveAmount, editor);
        }else{
            maintainLogisticDao.insertCardInventory(dealerId, cardDefId, receiveAmount, editor);
        }
        result.setSuccess(true);
        return true;
    }
    
    @Override
    public LogisticResultsDto handleImportInBackground(final String fileName,
        final InputStream in, final String templateFileName, final String templateName,
        final String sheetName, final String userId) throws AppException {
        try {
            List<LogisticDataDto>  dataList =  FileImportUtils.getImportedRecords(fileName, in, 
                    templateFileName, templateName, sheetName);
            return processLogistic(dataList,userId);
        } catch (Exception e) {
            throw new AppException("handleImportInBackground", e);
        }       
    }

    @Override
    public LogisticResultsDto processLogistic(List<LogisticDataDto> dataList, String userId) 
        throws AppException {
        try {
            List<LogisticImportResultDto>  dataListreturn = new ArrayList<LogisticImportResultDto>();
            LogisticResultsDto result = new LogisticResultsDto();
            for(int i = 0 ; i<dataList.size();i++) {
                LogisticImportResultDto rslt = new LogisticImportResultDto();
                LogisticDataDto data = dataList.get(i);
                if(Utils.isNullOrEmpty(data.getDealerNo()) 
                    || Utils.isNullOrEmpty(data.getShipDate())
                    || Utils.isNullOrEmpty(data.getEstimatedArriveDate())
                    || Utils.isNullOrEmpty(data.getCardName())
                    || Utils.isNullOrEmpty(data.getShipAmount())){
                    rslt.setLineNo(String.valueOf(i+2));
                    rslt.setShipDate(data.getShipDate());
                    rslt.setEstimateDate(data.getEstimatedArriveDate());
                    rslt.setCardName(data.getCardName());
                    rslt.setDealerNo(data.getDealerNo());
                    rslt.setReason(messageSource.getMessage(LogisticConstants.CANNOT_NULL, null, Locale.CHINA));
                    dataListreturn.add(rslt);
                }
                }
            if(!dataListreturn.isEmpty()) {
                result.setImportList(dataListreturn);
                result.setSuccess(true);
                return result;
            }
            maintainLogisticDao.deleteAll();
            maintainLogisticDao.saveLogisticToTemp(dataList);

            for(int i = 0 ; i<dataList.size();i++) {
                LogisticImportResultDto rslt = new LogisticImportResultDto();
                LogisticDataDto data = dataList.get(i);
                Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$"); 
                if((data!=null)&&
                    ((!pattern.matcher(data.getShipAmount()).matches())
                        ||(Integer.parseInt(data.getShipAmount())<=0))){
                    rslt.setLineNo(String.valueOf(i+2));
                    rslt.setShipDate(data.getShipDate());
                    rslt.setEstimateDate(data.getEstimatedArriveDate());
                    rslt.setCardName(data.getCardName());
                    rslt.setDealerNo(data.getDealerNo());
                    rslt.setReason(messageSource.getMessage(LogisticConstants.WRONG_AMOUNT, null, Locale.CHINA));
                    dataListreturn.add(rslt);
                }
                }
            dataListreturn.addAll(maintainLogisticDao.getWrongDealerNo());
            dataListreturn.addAll(maintainLogisticDao.getWrongCardName()); 
            dataListreturn.addAll(maintainLogisticDao.getWrongEstimate());  
            
            if(!dataListreturn.isEmpty()) {
                result.setImportList(dataListreturn);
                result.setSuccess(true);
                return result;
            }
            for(int i = 0 ; i<dataList.size();i++) {
                LogisticDataDto data = dataList.get(i);        
                if(data != null) {
                    String dealerId=maintainLogisticDao.getDealerId(data.getDealerNo());
                    String cardDefId=maintainLogisticDao.getCardId(data.getCardName());
                    data.setTransactionNo(uniqueCodeGenerateService.generateLogitsticNo());
                    data.setUserId(userId);
                    Date shipDate=Date.valueOf(data.getShipDate());
                    data.setShipDateVal(shipDate);
                    if(!Utils.isNullOrEmpty(data.getEstimatedArriveDate())){
                        Date estimatedArriveDate=Date.valueOf(data.getEstimatedArriveDate());
                        data.setEstimatedArriveDateVal(estimatedArriveDate);
                        }else{
                            data.setEstimatedArriveDateVal(null);
                        }
                    maintainLogisticDao.insertLogisticInfo(data, dealerId, cardDefId);
                }               
            }    
            result.setImportList(dataListreturn);
            result.setSuccess(true);
            return result;
        } catch (Exception e) {
            LOGGER.error(e);
            throw new AppException("processLogistic", e);
        }
        
    }
}
